//========================================================= 
/**@file ComDevice.h 
 * @brief Linux下串口设备
 * 
 * @date 2012-09-07   14:48:24 
 * @author Zhyioo 
 * @version 1.0
 */ 
//--------------------------------------------------------- 
#ifndef _LIBZHOUYB_LINUX_COMDEVICE_H_
#define _LIBZHOUYB_LINUX_COMDEVICE_H_
//---------------------------------------------------------  
#include "FileDevice.h"
//---------------------------------------------------------
namespace zhou_yb {
namespace base_device {
namespace env_linux {
//--------------------------------------------------------- 
/// 串口设备类
template<class THandlerDevice>
class ComHandlerAppender : public THandlerDevice
{
public:
    /// 将波特率转换为对应的串口速率
    static uint BaudToSpeed(uint baud)
    {
        switch(baud)
        {
            case 0: return B0;
            case 50: return B50;
            case 75: return B75;
            case 110: return B110;
            case 134: return B134;
            case 150: return B150;
            case 200: return B200;
            case 300: return B300;
            case 600: return B600;
            case 1200: return B1200;
            case 1800: return B1800;
            case 2400: return B2400;
            case 4800: return B4800;
            case 9600: return B9600;
            case 19200: return B19200;
            case 38400: return B38400;
            case 57600: return B57600;
            case 115200: return B115200;
            case 230400: return B230400;
        /* MAC下没有以下宏 */
        #ifndef __APPLE__
            case 460800: return B460800;
            case 500000: return B500000;
            case 576000: return B576000;
            case 921600: return B921600;
            case 1000000: return B1000000;
            case 1152000: return B1152000;
            case 1500000: return B1500000;
            case 2000000: return B2000000;
            case 2500000: return B2500000;
            case 3000000: return B3000000;
            case 3500000: return B3500000;
            case 4000000: return B4000000;
        #endif
        }
        return B9600;
    }
    /// 设置串口波特率
    bool SetIoSpeed(uint speed)
    {
        LOGGER(LoggerAdapter _log = THandlerDevice::_log);
        LOG_FUNC_NAME();
        ASSERT_DeviceValid(this->IsOpen());

        struct termios cfg;
        if(tcgetattr(THandlerDevice::_hDev.Handle, &cfg))
        {
            return this->_logRetValue(false);
        }

        cfmakeraw(&cfg);
        cfsetispeed(&cfg, speed);
        cfsetospeed(&cfg, speed);

        if(tcsetattr(THandlerDevice::_hDev.Handle, TCSANOW, &cfg))
        {
            return this->_logRetValue(false);
        }

        return this->_logRetValue(true);
    }
    /// 设置串口波特率
    inline bool SetBaud(uint baud)
    {
        return SetIoSpeed(BaudToSpeed(baud));
    }
    /// 获取串口属性
    inline bool GetTermio(struct termios* termio) const
    {
        LOGGER(LoggerAdapter _log = THandlerDevice::_log);
        LOG_FUNC_NAME();
        ASSERT_DeviceValid(this->IsOpen());

        if(tcgetattr(THandlerDevice::_hDev.Handle, termio))
            return this->_logRetValue(false);
        return this->_logRetValue(true);
    }
    /// 设置串口属性
    inline bool SetTermio(struct termios* termio)
    {
        LOGGER(LoggerAdapter _log = THandlerDevice::_log);
        LOG_FUNC_NAME();
        ASSERT_DeviceValid(this->IsOpen());

        if(tcsetattr(THandlerDevice::_hDev.Handle, termio))
            return this->_logRetValue(false);
        return this->_logRetValue(true);
    }
    //----------------------------------------------------- 
};
//--------------------------------------------------------- 
/// 串口设备(同步)
typedef ComHandlerAppender<FileDevice> ComDevice;
/// 串口设备(异步)
typedef ComHandlerAppender<AsyncFileDevice> AsyncComDevice;
//--------------------------------------------------------- 
} // namespace env_linux
} // namespace base_device 
} // namespace zhou_yb
//--------------------------------------------------------- 
#endif // _LIBZHOUYB_LINUX_COMDEVICE_H_
//========================================================= 
